//build:20240724
/**
 * To understand the basic components of a UI, you need to first understand some concepts.
 * 1. Layers: The device has two basic layers: the main layer and the top layer.
      The TOP layer is always above the main layer, and the TOP layer will not be blocked when switching pages on the main layer. The TOP layer is suitable for displaying status bars.
      The main layer can have multiple pages pre-constructed in memory, and then different pages can be loaded and switched using loadMain. The TOP layer, however, cannot be switched; it can only be hidden or deleted using UI objects.

 * 2. UI objects: There are many types of UI objects, the most basic of which is the 'view' object. The root UI object of the main layer and the top layer must be a 'view' object, and the remaining UI objects are all children of some UI object.
      UI objects include common ones like 'button', 'label', and 'image'. All objects have some common properties as well as some unique properties.
      All UI objects have a globally unique ID, which cannot be duplicated. Common properties also include...
      - type：Get the type of the UI object (string)
      - parent：Get the parent node of the UI object, string
      - children：Get the IDs of all child objects of the UI object, as a string array.

 * 3. dxui files: Files with the .dxui extension are UI trees generated using a visual drag-and-drop tool. The tool automatically generates corresponding JS files, which can be imported for manipulation.

 */

import utils from './uiUtils.js'
import button from './uiButton.js'
import font from './uiFont.js'
import image from './uiImage.js'
import label from './uiLabel.js'
import line from './uiLine.js'
import list from './uiList.js'
import dropdown from './uiDropdown.js'
import checkbox from './uiCheckbox.js'
import slider from './uiSlider.js'
import _switch from './uiSwitch.js'
import textarea from './uiTextarea.js'
import keyboard from './uiKeyboard.js'
import style from './uiStyle.js'
import view from './uiView.js'
import buttons from './uiButtons.js'

const dxui = {}
dxui.Button = button
dxui.Font = font
dxui.Image = image
dxui.Label = label
dxui.Line = line
dxui.List = list
dxui.Dropdown = dropdown
dxui.Checkbox = checkbox
dxui.Slider = slider
dxui.Switch = _switch
dxui.Textarea = textarea
dxui.Keyboard = keyboard
dxui.Style = style
dxui.View = view
dxui.Utils = utils
dxui.Buttons = buttons
let orientation = 1 //Default landscape mode
/**
 * Initialization must be called at the very beginning of the code.
 * @param {object} options Initialization parameters
 *        @param {number} options.orientation The screen orientation can be set to 0, 1, 2, or 3, representing portrait mode (screen on the left), landscape mode (screen on the top), portrait mode (screen on the right), and landscape mode (screen on the bottom), respectively.
 * @param {object} context Each application has a unique context variable. Different JavaScript files can reference dxUi.js, but the context must be consistent.
*/
dxui.init = function (options, context = {}) {
     this.initContext(context)
     if (options && options.orientation != undefined && options.orientation != null && [0, 1, 2, 3].includes(options.orientation)) {
          orientation = options.orientation
     }
     utils.GG.NativeDisp.lvDispSetRotation(orientation)
}
/**
 * Initialize the context. Each application has a unique context variable. Different JavaScript files can reference dxUi.js, but the context must be consistent.
 * Initialization is required before building the UI.
 * @param {object} context Initially, it is an empty object {}
 */
dxui.initContext = function (context) {
     utils.validateObject(context)
     dxui.all = context
     dxui.Button.all = dxui.all
     dxui.Image.all = dxui.all
     dxui.Label.all = dxui.all
     dxui.Line.all = dxui.all
     dxui.List.all = dxui.all
     dxui.Dropdown.all = dxui.all
     dxui.Checkbox.all = dxui.all
     dxui.Slider.all = dxui.all
     dxui.Switch.all = dxui.all
     dxui.Textarea.all = dxui.all
     dxui.Keyboard.all = dxui.all
     dxui.View.all = dxui.all
     dxui.Buttons.all = dxui.all
}
/**
 * Retrieve the constructed UI object by ID
 * @param {string} id 
 * @returns 
 */
dxui.getUi = function (id) {
     return dxui.all[id]
}
/**
 * The outer loop needs to call this method.
 */
dxui.handler = function () {
     return utils.GG.NativeTimer.lvTimerHandler()
}
/**
 * Obtain the screen orientation; different screen orientations may require loading different UI elements or different processing logic.
 * @returns The values ​​0, 1, 2, and 3 represent: portrait mode (screen on the left), landscape mode (screen on the top), portrait mode (screen on the right), and landscape mode (screen on the bottom), respectively.
 */
dxui.getOrientation = function () {
     return orientation;
}
/**
 * Create a timer that executes a callback function every milliseconds, primarily for periodically refreshing the value of a UI object.
 * The effect of setTimeout can be achieved by deleting the timer (clearInterval) in the callback function.
 * @param {string} id Unique identifier for timer (required)
 * @param {function} callback Callback function (can be an anonymous function)
 * @param {number} ms milliseconds
 * @param {object} user_data User data is passed to the callback parameter.
 * @returns Timer handle 
 */
dxui.setInterval = function (id, callback, ms, user_data) {
     if (utils.validateId(dxui.all, id))
          if (!callback || (typeof callback != 'function') || !callback.name || callback.name === '') {
               throw new Error('The callback should not be null and should be named function')
          }
     if (!ms || (typeof ms != 'number')) {
          throw new Error('The interval should not be empty, and should be number')
     }
     if (!this.all.__interval) {
          this.all.__interval = {}
     }
     this.all.__interval[id] = utils.GG.NativeTimer.lvTimerCreate(callback, ms, user_data)
}
/**
 * Once the timer is no longer needed, it can be deleted.
 * @param {string} id Timer ID 
 */
dxui.clearInterval = function (id) {
     if (!dxui.all[id]) {
          return
     }
     utils.GG.NativeTimer.lvTimerDel(dxui.all[id])
     delete dxui.all.__interval[id]
}
/**
 * Get the parent object of the UI object
 * @param {Object} ui 
 */
dxui.getParent = function (ui) {
     if (ui.parent) {
          return dxui.getUi(ui.parent)
     }
     return null
}
/**
 * Delete the current UI object
 */
dxui.del = function (ui) {
     function recursiveDelete(ui) {
          // If the object does not exist, return directly.
          if (!dxui.all[ui.id]) {
               return;
          }

          // First, recursively delete all child objects.
          if (ui.children && Array.isArray(ui.children)) {
               // Reverse traversal of child nodes
               for (let i = ui.children.length - 1; i >= 0; i--) {
                    const childId = ui.children[i];
                    if (dxui.all[childId]) {
                         recursiveDelete(dxui.all[childId]);
                    }
               }
          }
          // Remove the current object from the parent object.
          if (ui.parent && dxui.all[ui.parent] && Array.isArray(dxui.all[ui.parent].children)) {
               const children = dxui.all[ui.parent].children
               let index = children.indexOf(ui.id);
               if (index !== -1) {
                    children.splice(index, 1);
               }
          }

          // Delete the current object
          ui.obj.lvObjDel();
          delete dxui.all[ui.id];
     }

     // Start recursive deletion
     recursiveDelete(ui);
}
/**
 * Load (switch) the pre-built UI object on the main layer.
 * @param {object} ui UI objects built using the build function
 */
dxui.loadMain = function (ui) {
     if (!ui || !ui.obj) {
          throw new Error("dxui.loadMain:'ui' paramter should not be null")
     }
     // Loading home screen
     utils.GG.NativeDisp.lvScrLoad(ui.obj)
}
/**
 * Time elapsed since the last user activity (e.g., a click)
 * @returns Returns the elapsed time (in milliseconds) since the last activity.
 */
dxui.getIdleDuration = function () {
     return utils.GG.NativeDisp.lvDispGetInactiveTime()
}
/**
 * Reset the display of elapsed time for user activity (such as clicks).
 */
dxui.trigActivity = function () {
     utils.GG.NativeDisp.lvDispTrigActivity()
}

export default dxui;